home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
x11
/
strategy
/
xpat2-1.000
/
xpat2-1
/
xpat2-1.04
/
src
/
X-events.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-11-25
|
9KB
|
333 lines
/*****************************************************************************/
/* */
/* */
/* X patience version 2 -- module X-events.c */
/* */
/* Event handlers for the X interface */
/* written by Heiko Eissfeldt and Michael Bischoff */
/* see COPYRIGHT.xpat2 for Copyright details */
/* */
/* */
/*****************************************************************************/
#include "X-pat.h"
Display *dpy;
int screen;
unsigned long blackpixel;
unsigned long whitepixel;
GC blackgc;
GC whitegc;
#ifdef useXlib
static int intersect(int x1, int w1, int x2, int w2) {
if (x1 < x2)
return x1+w1 > x2;
else
return x2+w2 > x1;
}
#endif
/* events for Xlib AND Xaw interface */
/* event entry points are: key_press, button_press, button_release,
mouse_motion (only called with button 3 pressed) redraw_table */
void key_press(XKeyPressedEvent *xev) {
char str[32];
int num;
#define get_name_field() get_selection()
num = XLookupString(xev, str, 31, NULL, NULL);
if (num == 0)
return;
str[num] = '\0'; /* NULL to terminate it */
show_exposed_card(False);
key_pressed(str);
}
/* SPEEDUP does not work yet */
#ifdef SPEEDUP
static int pile_is_drawn[MAXPILES] = { 0, 0 };
static int buttons_are_drawn = 0;
#endif
extern int table_clear;
void redraw_table(XExposeEvent *xev) {
int i;
table_clear = 0;
#ifdef useXlib
if (intersect(0, graphic.buttons_height, xev->y, xev->height))
#ifdef SPEEDUP
if (!buttons_are_drawn++)
#endif
redraw_buttons(xev->x, xev->y, xev->width, xev->height, table, button.num, button.b);
if (intersect(graphic.buttons_height, graphic.message_height, xev->y, xev->height))
show_message(NULL);
if (xev->count && xev->y + xev->height < graphic.yoff) /* else may miss the last event */
return;
#endif
#ifdef LABER
printf("request for expose %d,%d of size %d,%d, cnt %d\n", xev->x, xev->y, xev->width, xev->height, xev->count);
#endif
for (i = 0; i < game.numpiles; ++i) {
struct pile *p;
#ifdef SPEEDUP
if (pile_is_drawn[i]++)
continue;
#endif
p = graphic.pile + i;
if (NOT_DISPLAYED(p) ||
xev->y >= p->y + p->ytotal || xev->y + xev->height <= p->y ||
xev->x >= p->x + p->xtotal || xev->x + xev->width <= p->x)
continue; /* this pile is not affected */
#ifdef LABER
printf("request for update pile %d of pos %d,%d, size %d,%d\n", i,
p->x, p->y, p->xtotal, p->ytotal);
#endif
draw_pileupdate(i, 0);
}
if (!xev->count) {
show_arrow(2); /* Update hint arrow */
}
#ifdef LABER
if (!xev->count)
printf(" => last expose-table call\n");
#endif
#ifdef SPEEDUP
if (xev->count)
return;
/* was last event, unmark piles */
for (i = 0; i < MAXPILES; ++i)
pile_is_drawn[i] = 0;
buttons_are_drawn = 0;
#endif
}
/* the pointer is somewhere in the area of pile i */
/* check, if a card has to be exposed */
static void expose_card(Pileindex i, int y) {
struct pile *p;
Cardindex ind;
if (EMPTY(i))
return;
p = graphic.pile + i;
ind = game.ind[i];
while (ind != INDEX_OF_LAST_CARD(i) && y >= p->y + graphic.cardy[ind+1])
++ind;
if (ind == INDEX_OF_LAST_CARD(i)) /* the most bottom card don't has to */
ind = -1; /* be put on foreground */
if (graphic.zoomed_card != ind) { /* change of state */
show_exposed_card(False); /* hide it */
/* graphic.zoomed_card is now -1 */
if (ind >= 0) {
graphic.zoomed_card = ind;
show_exposed_card(True);
}
}
}
void mouse_motion(XPointerMovedEvent *xev) {
Pileindex i;
/* find new pile */
for (i = FIRST_SLOT; i <= LAST_SLOT; ++i) {
struct pile *p;
p = graphic.pile+i;
if (xev->x >= p->x && xev->x < p->x + p->xmaxwidth &&
xev->y >= p->y && xev->y < p->y + p->ymaxheight) {
/* yeah, a slot is hit */
/* find out which card is the target */
expose_card(i, xev->y);
return;
}
}
/* pointer moved out of scope: */
show_exposed_card(False);
}
void button_release(XButtonPressedEvent *xev) {
show_exposed_card(False);
}
void button_press(XButtonPressedEvent *xev) {
Pileindex i;
show_exposed_card(False);
#ifdef useXlib
{ void (*func)(void);
func = check_button_list(button.b, button.num, xev);
/* check for hit button */
if (func) {
(*func)();
return;
}
}
#endif
for (i = 0; i < game.numpiles; ++i) {
struct pile *p;
p = graphic.pile+i;
if (NOT_DISPLAYED(p))
continue;
if (xev->x >= p->x && xev->x < p->x + p->xmaxwidth &&
xev->y >= p->y && xev->y < p->y + p->ymaxheight) {
Cardindex cardi;
if EMPTY(i)
cardi = -1;
else {
cardi = INDEX_OF_LAST_CARD(i);
if (game.piletype[i] == Slot)
/* possibly a different card */
while (cardi != INDEX_OF_FIRST_CARD(i) &&
graphic.cardy[cardi] > xev->y - graphic.pile[i].y)
--cardi;
}
switch (xev->button) {
case Button1: /* quick move */
button_pressed(i, cardi, 1);
break;
case Button2: /* select / deselect */
button_pressed(i, cardi, 2);
break;
case Button3:
#ifdef BUTTON_3_DRAGS_CARD
button_pressed(i, cardi, 3);
#else
#ifndef useXview
if (game.piletype[i] == Slot)
expose_card(i, xev->y);
#else
if (game.piletype[i] == Slot &&
xev->y < graphic.pile[i].y + graphic.cardy[cardi] +
CARD_HEIGHT)
expose_card(i, xev->y);
else
{
menu_show(cmenu, canvas, bp_event, 0);
return;
}
#endif
break;
#endif
}
return;
}
}
#ifdef useXview
if (xev->button == Button3)
{
menu_show(cmenu, canvas, bp_event, 0);
return;
}
#endif
button_pressed(-1, -1, -1); /* cancel action */
}
/*****************************************************************************/
/* */
/* Functions for resize events and resize requests */
/* */
/*****************************************************************************/
/* 1) hard resizes (i.e. forcing the outer window to change size) */
/* I think these are not liked in the Xaw community */
void cmd_MinWindow(void) {
XSize_t w, h;
w = graphic.min_width;
h = graphic.min_height;
Force_Resize(w, h);
}
void cmd_PreferredWindow(void) {
XSize_t w, h;
w = graphic.preferred_width;
h = graphic.preferred_height;
Force_Resize(w, h);
}
/* event handler function. This function is called by the Widget in response
to a request from us. In Xaw, this is a resize of the logical area, i.e.
of the virtual size of the tableau. */
void resize_event(XSize_t w, XSize_t h) {
#ifdef LABER
printf("resize event to (%d,%d) called\n", w, h);
#endif
if (game.graphic)
cmd_ResetHints();
if (graphic.height == h && graphic.width == w)
return; /* no change of size */
/* in xlib, we must clear the new area by hand; there may be illegal data
left in the server. This applies to Xaw as well */
{ XExposeEvent xev;
xev.count = -1;
if (game.graphic) {
if (graphic.height < h) {
/* window is greater now */
XClearArea(dpy, table, 0, graphic.height, graphic.width, h - graphic.height, True);
++xev.count;
}
if (graphic.width < w) {
/* window is greater now */
XClearArea(dpy, table, graphic.width, 0, w - graphic.width, h, True);
++xev.count;
}
if (xev.count >= 0) {
/* generate synthetic expose events for the new area */
/* this must be done before we possibly change the layout */
if (graphic.height < h) {
/* window is greater now */
xev.x = 0;
xev.y = graphic.height;
xev.width = graphic.width;
xev.height = h - graphic.height;
redraw_table(&xev);
--xev.count;
}
if (graphic.width < w) {
/* window is greater now */
xev.x = graphic.width;
xev.y = 0;
xev.width = w - graphic.width;
xev.height = h;
redraw_table(&xev);
}
}
}
}
graphic.height = h;
graphic.width = w;
if (!game.graphic)
return;
#ifdef useXlib
confirm.x = (graphic.width - confirm.w) / 2;
confirm.y = (graphic.height - confirm.h) / 2;
XMoveWindow(dpy, confirm.win, confirm.x, confirm.y);
#endif
if (graphic.autolayout) {
cmd_Layout(); /* change everything */
} else {
Pileindex i;
/* fix piles THIS IS WRONG FOR 2-ROW LAYOUTS!!!! FIX THIS! */
for (i = 0; i < rules.numslots; ++i)
graphic.pile[SLOT(i)].ymaxheight = graphic.height - graphic.pile[SLOT(i)].y;
for (i = FIRST_SLOT; i <= LAST_SLOT; ++i)
if (pile_resize(i))
draw_pileupdate(i, 0);
}
}